package com.xiaoq.order.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.xiaoq.apis.interpreter.IInterpreterApi;
import com.xiaoq.apis.user.IPushMessageApi;
import com.xiaoq.apis.user.IUserApi;
import com.xiaoq.apis.user.UserPhone4OrderVo;
import com.xiaoq.coms.util.CommonUtil;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.order.entity.ShopOrderEntity;
import com.xiaoq.order.service.IShopOrderService;
import com.xiaoq.schedule.order.IOrderScheduleApi;
import com.xiaoq.shop.entity.CouponEntity;
import com.xiaoq.shop.entity.UserCouponEntity;
import com.xiaoq.shop.service.ICouponService;
import com.xiaoq.shop.service.IUserCouponService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by chenjh on 2018/3/3.
 */
@Service(interfaceClass=IOrderScheduleApi.class, version="1.0.0")
public class OrderScheduleApiImpl implements IOrderScheduleApi {

    private Logger logger = LoggerFactory.getLogger(OrderScheduleApiImpl.class);

    @Autowired
    private IShopOrderService orderService;

    @Autowired
    private IUserCouponService userCouponService;

    @Autowired
    private ICouponService couponService;

    @Reference(interfaceClass=IUserApi.class, check=false, version="1.0.0")
    private IUserApi userApi;

    @Reference(interfaceClass=IPushMessageApi.class, check=false, version="1.0.0")
    private IPushMessageApi pushMessageApi;

    @Reference(interfaceClass=IInterpreterApi.class, check=false, version="1.0.0")
    private IInterpreterApi interpreterApi;

    @Override
    public void cancelOverTimeNotPay4TicketOrder() {
        logger.error("***********cancelOverTimeNotPay4TicketOrder 定时任务取消订单：" + new DateTime().toLocalDateTime());
        List<ShopOrderEntity> orderEntityList = orderService.getNotPayExpiredShopOrderList(null, ConstantUtil.ORDER_TYPE_TICKET);
        if(CollectionUtils.isNotEmpty(orderEntityList)){
            for(ShopOrderEntity shopOrderEntity : orderEntityList){
                String orderId = shopOrderEntity.getShopOrderId();
                boolean retFlag = orderService.cancelOrder(orderId, shopOrderEntity.getUserId());
            }
        }
    }

    @Override
    public void cancelOverTimeNotPay4InterpreterOrder() {
        logger.error("***********cancelOverTimeNotPay4InterpreterOrder 定时任务取消订单：" + new DateTime().toLocalDateTime());
        List<ShopOrderEntity> orderEntityList = orderService.getNotPayExpiredShopOrderList(null, ConstantUtil.ORDER_TYPE_INTERPRETER);
        if(CollectionUtils.isNotEmpty(orderEntityList)){
            for(ShopOrderEntity shopOrderEntity : orderEntityList){
                String orderId = shopOrderEntity.getShopOrderId();
                boolean retFlag = orderService.cancelOrder(orderId, shopOrderEntity.getUserId());
                if(retFlag && StringUtils.isNotBlank(shopOrderEntity.getInterpreterId())){
                    boolean retInterFlag = false;
                    try {
                        //更新讲解员至可预约状态
                        retInterFlag = interpreterApi.updateInter2CanAppoint(shopOrderEntity.getInterpreterId(),
                                shopOrderEntity.getShopId());
                        if(retInterFlag){
                            interpreterApi.updateInterCalendarStatus(orderId, ConstantUtil.INTERPRETER_CALENDAR_STATUS_CANCEL);
                        }
                    }catch (Exception e){
                        logger.error("释放讲解员失败 interId: " + shopOrderEntity.getInterpreterId());
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        }
    }


    /**
     * 推送即将过期(未使用)的优惠券,
     *
     * 比如今天22号, 则推送到期日 26 的优惠券
     */
    @Override
    public void pushCouponMessage4QuickExpired() {
        logger.error("***********pushCouponMessage4QuickExpired 定时任务取消订单：" + new DateTime().toLocalDateTime());
        List<CouponEntity> couponList = couponService.getAllCoupon4NotifyNotExpired(ConstantUtil.COUPON_NOTIFY);
        logger.error("***********couponList size：" + couponList.size());
        Set<String> userIdSet = new HashSet<>();
        Date now = new Date();

        if(CollectionUtils.isNotEmpty(couponList)){
            List<String> couponInstanceCodeList = new ArrayList<>();
            for(CouponEntity couponEntity : couponList){
                if(couponEntity.getExpirationDate() != null){
                    Integer betweenDate = CommonUtil.getApartDays(now, new Date(couponEntity.getExpirationDate()));
                    if(betweenDate != null && betweenDate == 4){
                        couponInstanceCodeList.add(couponEntity.getId());
                    }
                }
            }

            List<UserCouponEntity> userCouponList = userCouponService.getUserCouponList4Schedule(couponInstanceCodeList, null);
            logger.error("***********userCouponList  size：" + userCouponList.size());
            if(CollectionUtils.isNotEmpty(userCouponList)){

                BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(userCouponList.size());
                ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4, 4, 0, TimeUnit.SECONDS, workQueue);
                for(UserCouponEntity userCouponEntity : userCouponList){
                    logger.error("***********userIdSet  size：" + userIdSet.toString());
                    if(!userIdSet.contains(userCouponEntity.getUserId())){
                        userIdSet.add(userCouponEntity.getUserId());
                        threadPoolExecutor.execute(new SendMessageRunnable(userCouponEntity));
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Date now = new Date();
        //DateTime dateTime = new DateTime(now.getTime() + 4*1000 * 60 * 60 * 24);
//        System.out.println(dateTime.toLocalDateTime());

        System.out.println((1524465263000L-now.getTime())/(1000 * 60 * 60 * 24));

    }


    private class SendMessageRunnable implements Runnable {

        private UserCouponEntity userCouponEntity;

        public SendMessageRunnable(UserCouponEntity userCouponEntity){
            this.userCouponEntity = userCouponEntity;
        }

        @Override
        public void run() {
            try {
                String title = "优惠券到期提醒";
                String content = "您有优惠券即将到期，赶紧去使用吧";
                /**
                 * @param userId  C端的userId
                 * @param catalogueCode 板块code 1系统消息,2订单消息,3通知消息
                 * @param msgTitle  消息title
                 * @param msgContent  消息内容
                 * @param mesTarId  消息代表的具体内容Id 如果是票那就是票Id,讲解员Id等
                 * @param mesType  每种消息的分类 1系统消息，2,门票订单，3，讲解员订单，4，优惠劵过期，5活动海报，6旅行头条，7优惠券详情
                 * @param shopId 小店Id 可以传null
                 * @return
                 */
                boolean retFlag = pushMessageApi.sendMessage(userCouponEntity.getUserId(), String.valueOf(3), title, content, userCouponEntity.getUserId(),String.valueOf(4), userCouponEntity.getShopId());
                if(!retFlag){
                    logger.error("推送优惠券即将过期提醒失败(userId): " + userCouponEntity.getUserId());
                }else {
                    logger.error("推送优惠券即将过期提醒成功(userId):   " + retFlag);
                }

            }catch (Exception e){
                logger.error(e.getMessage(), e);
            }
        }
    }


    @Override
    public void updateUserFrom4ShopOrders() {
        logger.error("***********updateUserFrom4ShopOrders 更新用户所属地：" + new DateTime().toLocalDateTime());
        List<ShopOrderEntity> orderList = orderService.getPaidNotUserFromOrders(30);

        if(CollectionUtils.isNotEmpty(orderList)){
            List<String> userIdList = new ArrayList<>();
            for(ShopOrderEntity shopOrderEntity : orderList){
                userIdList.add(shopOrderEntity.getUserId());
            }
            List<UserPhone4OrderVo> userPhone4OrderVoList = userApi.getUserPhone4OrderTourByUserIds(userIdList);

            Map<String, UserPhone4OrderVo> userId2UserPhoneMap = new HashMap<>();
            if(CollectionUtils.isNotEmpty(userPhone4OrderVoList)){
                for(UserPhone4OrderVo userPhone4OrderVo : userPhone4OrderVoList){
                    userId2UserPhoneMap.put(userPhone4OrderVo.getUserId(), userPhone4OrderVo);
                }
            }

            UserPhone4OrderVo userPhone4OrderVo = null;
            for(ShopOrderEntity shopOrderEntity : orderList){
                if((userPhone4OrderVo = userId2UserPhoneMap.get(shopOrderEntity.getUserId())) != null){
                    Boolean phoneValid = userPhone4OrderVo.getPhoneValid();
                    if(phoneValid != null){
                        if(phoneValid){
                            ShopOrderEntity updateOrder = new ShopOrderEntity();
                            updateOrder.setId(shopOrderEntity.getId());
                            updateOrder.setShopOrderId(shopOrderEntity.getShopOrderId());
                            updateOrder.setUserFrom(userPhone4OrderVo.getCity());
                            orderService.updateShopOrderByOrderId(updateOrder);
                        }else {
                            ShopOrderEntity updateOrder = new ShopOrderEntity();
                            updateOrder.setId(shopOrderEntity.getId());
                            updateOrder.setShopOrderId(shopOrderEntity.getShopOrderId());
                            updateOrder.setUserFrom("空");
                            orderService.updateShopOrderByOrderId(updateOrder);
                        }
                    }

                }
            }
        }
    }
}
